package com.pactera.madp.cp.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pactera.madp.admin.api.constant.CrmDictTypeConstants;
import com.pactera.madp.admin.api.entity.SysDictItem;
import com.pactera.madp.common.core.util.R;
import com.pactera.madp.cp.api.dto.contact.ContactByTagDto;
import com.pactera.madp.cp.api.em.MarketingEventRemindTypeEnum;
import com.pactera.madp.cp.api.entity.*;
import com.pactera.madp.cp.api.entity.clientLossManagement.RemindCommunicationEntity;
import com.pactera.madp.cp.api.entity.crm.WorkDkfinaExpireInfoEntity;
import com.pactera.madp.cp.api.entity.crm.WorkFinaExpireInfoEntity;
import com.pactera.madp.cp.api.entity.crm.WorkImportantDaysInfoEntity;
import com.pactera.madp.cp.api.entity.crm.WorkPreSavedeptInfoEntity;
import com.pactera.madp.cp.api.entity.sync.MaMarketingLeadDetailsEntity;
import com.pactera.madp.cp.api.entity.sync.MaMarketingLeadEntity;
import com.pactera.madp.cp.api.entity.wm.WorkMsgEntity;
import com.pactera.madp.cp.api.feign.RemoteDictService;
import com.pactera.madp.cp.api.page.SubPage;
import com.pactera.madp.cp.api.vo.*;
import com.pactera.madp.cp.api.vo.contact.ContactEmployeeTagVO;
import com.pactera.madp.cp.api.vo.contactloss.SidebarNoCommunicationVO;
import com.pactera.madp.cp.common.constant.BehaviorTrackFormatConst;
import com.pactera.madp.cp.common.util.DateUtils;
import com.pactera.madp.cp.common.util.PageUtil;
import com.pactera.madp.cp.common.util.WxApiUtils;
import com.pactera.madp.cp.common.util.wm.WorkMsgHelper;
import com.pactera.madp.cp.handler.CorpContextHolder;
import com.pactera.madp.cp.mapper.ContactMapper;
import com.pactera.madp.cp.mapper.RemindContentViewTimeMapper;
import com.pactera.madp.cp.mapper.WorkContactEmployeeMapper;
import com.pactera.madp.cp.mapper.wm.WorkMsgMapper;
import com.pactera.madp.cp.service.*;
import com.pactera.madp.cp.service.sync.MaMarketingLeadDetailsService;
import com.pactera.madp.cp.service.sync.MaMarketingLeadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.Local;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.pactera.madp.cp.common.constant.BehaviorTrackFormatConst.Manager_View_URL;

/**
 * @author zkd
 * @date 2022/5/6 10:00
 */
@Service
@Slf4j
public class EmployeeMarketingEventRemindServiceImpl implements EmployeeMarketingEventRemindService {

    @Autowired
    private RemindCommunicationService remindCommunicationService;
    @Autowired
    private IWorkEmployeeService workEmployeeService;
    @Autowired
    private ContactMapper contactMapper;
    @Autowired
    private WorkMsgMapper workMsgMapper;
    @Autowired
    private RemindContentViewTimeService remindContentViewTimeService;
    @Autowired
    private IContactService contactService;
    @Autowired
    private IWorkEmployeeService employeeService;
    @Autowired
    private WorkContactEmployeeMapper workContactEmployeeMapper;
    @Autowired
    private WorkDkfinaExpireInfoService workDkfinaExpireInfoService;
    @Autowired
    private WorkFinaExpireInfoService workFinaExpireInfoService;
    @Autowired
    private WorkImportantDaysInfoService workImportantDaysInfoService;
    @Autowired
    private WorkPreSavedeptInfoService workPreSavedeptInfoService;
    @Autowired
    private RemoteDictService remoteDictService;
    @Autowired
    private MaMarketingLeadService marketingLeadService;
    @Autowired
    private RadarContactService radarContactService;
    @Autowired
    private MaMarketingLeadDetailsService marketingLeadDetailsService;
    @Autowired
    private ICorpService corpService;

    @Override
    public MarketingEventRemindOverviewVO getOverViewData(String wxUserId) {
        LocalDateTime nowTime = LocalDateTime.now();
        List<RemindContentViewTimeEntity> viewTimeEntities = remindContentViewTimeService.list(new LambdaQueryWrapper<RemindContentViewTimeEntity>()
                .eq(RemindContentViewTimeEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(RemindContentViewTimeEntity::getWxUserId, wxUserId));
        //产品到期
        MarketingEventRemindOverviewVO.ProductExpireVO productExpireVO = new MarketingEventRemindOverviewVO.ProductExpireVO();
        Integer productExpireCount = getProductExpireCountByWxUserId(wxUserId);
        productExpireVO.setCount(productExpireCount);
        List<RemindContentViewTimeEntity> productExpireViewTime = viewTimeEntities.stream()
                .filter(v -> v.getViewType().equals(MarketingEventRemindTypeEnum.PRODUCT_EXPIRE.getCode()))
                .collect(Collectors.toList());
        if (productExpireViewTime.isEmpty() && productExpireCount != 0) {
            productExpireVO.setViewStatus(0);
        } else if (productExpireCount == 0) {
            productExpireVO.setViewStatus(1);
        } else {
            String viewDate = DateUtil.format(productExpireViewTime.get(0).getViewTime(), "yyyy-MM-dd");
            String nowDate = DateUtil.format(nowTime, "yyyy-MM-dd");
            productExpireVO.setViewStatus(viewDate.equals(nowDate) ? 1 : 0);
        }



        //生日提醒
        MarketingEventRemindOverviewVO.BirthdayRemindVO birthdayRemindVO = new MarketingEventRemindOverviewVO.BirthdayRemindVO();
        Integer birthdayRemindCount = getBirthdayRemindCountByWxUserId(wxUserId);
        birthdayRemindVO.setCount(birthdayRemindCount);
        List<RemindContentViewTimeEntity> birthdayRemindViewTime = viewTimeEntities.stream()
                .filter(v -> v.getViewType().equals(MarketingEventRemindTypeEnum.BIRTHDAY_REMIND.getCode()))
                .collect(Collectors.toList());
        if (birthdayRemindViewTime.isEmpty() && birthdayRemindCount != 0) {
            birthdayRemindVO.setViewStatus(0);
        } else if (birthdayRemindCount == 0) {
            birthdayRemindVO.setViewStatus(1);
        } else {
            String viewDate = DateUtil.format(birthdayRemindViewTime.get(0).getViewTime(), "yyyy-MM-dd");
            String nowDate = DateUtil.format(nowTime, "yyyy-MM-dd");
            birthdayRemindVO.setViewStatus(viewDate.equals(nowDate) ? 1 : 0);
        }


        //活期余额
        MarketingEventRemindOverviewVO.CurrentBalanceVO currentBalanceVO = new MarketingEventRemindOverviewVO.CurrentBalanceVO();
        Integer currentBalanceCount = getCurrentBalanceCountByWxUserId(wxUserId);
        currentBalanceVO.setCount(currentBalanceCount);
        List<RemindContentViewTimeEntity> currentBalanceViewTime = viewTimeEntities.stream()
                .filter(v -> v.getViewType().equals(MarketingEventRemindTypeEnum.CURRENT_BALANCE.getCode()))
                .collect(Collectors.toList());
        if (currentBalanceViewTime.isEmpty() && currentBalanceCount != 0) {
            currentBalanceVO.setViewStatus(0);
        } else if (currentBalanceCount == 0) {
            currentBalanceVO.setViewStatus(1);
        } else {
            String viewDate = DateUtil.format(currentBalanceViewTime.get(0).getViewTime(), "yyyy-MM-dd");
            String nowDate = DateUtil.format(nowTime, "yyyy-MM-dd");
            currentBalanceVO.setViewStatus(viewDate.equals(nowDate) ? 1 : 0);
        }


        //营销线索
        MarketingEventRemindOverviewVO.MarketingClueVO marketingClueVO = new MarketingEventRemindOverviewVO.MarketingClueVO(0, 1);
        Integer marketingClueCount = getMarketingClueCountByWxUserId(wxUserId);
        marketingClueVO.setCount(marketingClueCount);
        List<RemindContentViewTimeEntity> marketingClueViewTime = viewTimeEntities.stream()
                .filter(v -> v.getViewType().equals(MarketingEventRemindTypeEnum.MARKETING_CLUE.getCode()))
                .collect(Collectors.toList());
        if (marketingClueViewTime.isEmpty() && marketingClueCount != 0) {
            marketingClueVO.setViewStatus(0);
        } else if (marketingClueCount == 0) {
            marketingClueVO.setViewStatus(1);
        } else {
            String viewDate = DateUtil.format(marketingClueViewTime.get(0).getViewTime(), "yyyy-MM-dd");
            String nowDate = DateUtil.format(nowTime, "yyyy-MM-dd");
            marketingClueVO.setViewStatus(viewDate.equals(nowDate) ? 1 : 0);
        }


        //未交流客户
        MarketingEventRemindOverviewVO.NoCommunicationContactVO noCommunicationContactVO = new MarketingEventRemindOverviewVO.NoCommunicationContactVO();
        Integer noCommunicationContactCount = getNoCommunicationContactCountByWxUserId(CorpContextHolder.getCorpId(),wxUserId);
        noCommunicationContactVO.setCount(noCommunicationContactCount);
        List<RemindContentViewTimeEntity> noCommunicationContactViewTime = viewTimeEntities.stream()
                .filter(v -> v.getViewType().equals(MarketingEventRemindTypeEnum.NO_COMMUNICATION.getCode()))
                .collect(Collectors.toList());
        if (noCommunicationContactViewTime.isEmpty() && noCommunicationContactCount != 0) {
            noCommunicationContactVO.setViewStatus(0);
        } else if (noCommunicationContactCount == 0) {
            noCommunicationContactVO.setViewStatus(1);
        } else {
            String viewDate = DateUtil.format(noCommunicationContactViewTime.get(0).getViewTime(), "yyyy-MM-dd");
            String nowDate = DateUtil.format(nowTime, "yyyy-MM-dd");
            noCommunicationContactVO.setViewStatus(viewDate.equals(nowDate) ? 1 : 0);
        }


        MarketingEventRemindOverviewVO vo = new MarketingEventRemindOverviewVO();
        vo.setProductExpireVO(productExpireVO);
        vo.setBirthdayRemindVO(birthdayRemindVO);
        vo.setCurrentBalanceVO(currentBalanceVO);
        vo.setNoCommunicationContactVO(noCommunicationContactVO);
        vo.setMarketingClueVO(marketingClueVO);
        return vo;
    }

    private Integer getProductExpireCountByWxUserId(String wxUserId) {
        Integer totalCount = 0;
        Integer finaExpireCount = workFinaExpireInfoService.count(new LambdaQueryWrapper<WorkFinaExpireInfoEntity>()
                .eq(WorkFinaExpireInfoEntity::getWarnPerson, wxUserId));
        Integer dkfinaExpireCount = workDkfinaExpireInfoService.count(new LambdaQueryWrapper<WorkDkfinaExpireInfoEntity>()
                .eq(WorkDkfinaExpireInfoEntity::getWarnPerson, wxUserId));
        totalCount = finaExpireCount + dkfinaExpireCount;
        return totalCount;
    }


    private Integer getBirthdayRemindCountByWxUserId(String wxUserId) {
        return workImportantDaysInfoService.count(new LambdaQueryWrapper<WorkImportantDaysInfoEntity>()
                .eq(WorkImportantDaysInfoEntity::getWarnPerson,wxUserId));
    }

    private Integer getCurrentBalanceCountByWxUserId(String wxUserId) {
        return workPreSavedeptInfoService.count(new LambdaQueryWrapper<WorkPreSavedeptInfoEntity>()
                .eq(WorkPreSavedeptInfoEntity::getWarnPerson,wxUserId));
    }

    private Integer getMarketingClueCountByWxUserId(String wxUserId) {
        return marketingLeadService.count(new LambdaQueryWrapper<MaMarketingLeadEntity>()
                .eq(MaMarketingLeadEntity::getRecommendId,wxUserId)
                .eq(MaMarketingLeadEntity::getMaDate,DateUtil.format(DateUtil.yesterday(),"yyyy-MM-dd")));
    }


    private Integer getNoCommunicationContactCountByWxUserId(Integer corpId,String wxUserId) {
        Integer count = 0;
        RemindCommunicationEntity communicationEntity = remindCommunicationService.getOne(Wrappers.<RemindCommunicationEntity>lambdaQuery().eq(RemindCommunicationEntity::getCorpId, corpId).orderByDesc(BaseEntity::getCreateTime).last("limit 1"));
        //未交流客户配置
        if(null==communicationEntity){
            log.error("未交流提醒已关闭");
            return count;
        }
        List<Integer> tagIds = JSONUtil.toList(JSONUtil.parseArray(communicationEntity.getTagIds()),Integer.class);
        if (tagIds.isEmpty()) {
            return count;
        }
        //该用户名下符合条件的客户
        WorkEmployeeEntity workEmployeeServiceOne = workEmployeeService.getOne(Wrappers.<WorkEmployeeEntity>lambdaQuery()
                .select(WorkEmployeeEntity::getName)
                .eq(WorkEmployeeEntity::getWxUserId, wxUserId)
                .eq(WorkEmployeeEntity::getCorpId, corpId));
        List<ContactByTagDto> contactByTagDtoList = contactMapper.getContactByEmployee(corpId, tagIds, workEmployeeServiceOne.getName());
        if(contactByTagDtoList.size()==0){
            return count;
        }
        for (ContactByTagDto contact : contactByTagDtoList) {
            //聊天记录
            WorkMsgEntity workMsgEntity = workMsgMapper.countTime(contact.getWxUserId(), contact.getWxExternalUserid(), corpId);
            if (null == workMsgEntity) {
                continue;
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date nowTime = DateUtils.asDate(LocalDateTime.now());
            Date endTime = DateUtils.asDate(DateUtils.asLocalDateTime(sdf.format(new Date(Long.parseLong(workMsgEntity.getMsgTime())))));
            //未交流天数
            long between = DateUtil.between(endTime, nowTime, DateUnit.DAY);
            if (between > communicationEntity.getTime()) {
                count++;
            }
        }
        return count;
    }


    @Override
    public IPage<SidebarNoCommunicationVO> getNoCommunicationPage(Page page, String wxUserId) {
        WorkEmployeeEntity employeeEntity = employeeService.getWorkEmployeeByCorpIdAndWxUserId(CorpContextHolder.getCorpId(), wxUserId);
        if (employeeEntity == null) {
            throw new IllegalArgumentException("不存在的wxUserId:"+wxUserId);
        }
        IPage<ContactEmployeeTagVO> contactEmployeeTagVOPage = contactService.getContactListByUser(page, employeeEntity.getId());
        ArrayList<SidebarNoCommunicationVO> voList = new ArrayList<>();
        contactEmployeeTagVOPage.getRecords().forEach(record->{
            SidebarNoCommunicationVO vo = workContactEmployeeMapper.getContactEmployeeInfo(CorpContextHolder.getCorpId(), record.getContactId(), record.getEmployeeId());
            voList.add(vo);
        });
        SubPage subPage = new SubPage();
        subPage.setRecords(voList);
        subPage.setCurrent(contactEmployeeTagVOPage.getCurrent());
        subPage.setSize(contactEmployeeTagVOPage.getSize());
        subPage.setTotal(contactEmployeeTagVOPage.getTotal());

        //记录查看时间
        RemindContentViewTimeEntity viewTime = remindContentViewTimeService.getOne(new LambdaQueryWrapper<RemindContentViewTimeEntity>()
                .eq(RemindContentViewTimeEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(RemindContentViewTimeEntity::getWxUserId, wxUserId)
                .eq(RemindContentViewTimeEntity::getViewType, MarketingEventRemindTypeEnum.NO_COMMUNICATION.getCode()));
        RemindContentViewTimeEntity viewTimeEntity = new RemindContentViewTimeEntity();
        viewTimeEntity.setCorpId(CorpContextHolder.getCorpId());
        viewTimeEntity.setCurrentCount((int)contactEmployeeTagVOPage.getTotal());
        viewTimeEntity.setWxUserId(wxUserId);
        viewTimeEntity.setViewTime(LocalDateTime.now());
        viewTimeEntity.setViewType(MarketingEventRemindTypeEnum.NO_COMMUNICATION.getCode());
        viewTimeEntity.setId(viewTime == null ? null : viewTime.getId());
        if (viewTime == null) {
            remindContentViewTimeService.save(viewTimeEntity);
        } else {
            remindContentViewTimeService.updateById(viewTimeEntity);
        }
        return subPage;
    }

    @Override
    public IPage<SidebarProductExpireVO> getProductExpirePage(Page page, String wxUserId, String queryParam) {
        List<Map<String, String>> mobileAndWxExternalUseridMapList = contactService.getMobileAndWxExternalUseridByWxUserId(wxUserId);
        List<WorkFinaExpireInfoEntity> workFinaExpireInfoEntities = workFinaExpireInfoService.list(new LambdaQueryWrapper<WorkFinaExpireInfoEntity>()
                .eq(WorkFinaExpireInfoEntity::getWarnPerson, wxUserId));
        List<WorkDkfinaExpireInfoEntity> workDkfinaExpireInfoEntities = workDkfinaExpireInfoService.list(new LambdaQueryWrapper<WorkDkfinaExpireInfoEntity>()
                .eq(WorkDkfinaExpireInfoEntity::getWarnPerson, wxUserId));
        ArrayList<SidebarProductExpireVO> vos = new ArrayList<>();
        workFinaExpireInfoEntities.forEach(entity->{
            SidebarProductExpireVO vo = new SidebarProductExpireVO();
            vo.setCustNo(entity.getCustNo());
            vo.setAvatar(radarContactService.getAvatarByCustNo(entity.getCustNo()));
            vo.setCustName(entity.getPecustName());
            vo.setMobile(entity.getMobileTel());
            vo.setCustMgrName(entity.getWarnPersonName());
            vo.setBelongOrgName(entity.getBelongOrg());
            vo.setWxExternalUserid(findWxExternalUseridByMobile(entity.getMobileTel(),mobileAndWxExternalUseridMapList));
            vo.setDataDate(DateUtil.parse(entity.getDataDt(), "yyyyMMdd").toDateStr());
            vo.setProductType("1");
            vo.setProductName(entity.getProductName());
            vo.setProductCode(entity.getProductCode());
            vo.setExpireDate(DateUtil.parse(entity.getExpireDt(), "yyyyMMdd").toDateStr());
            vo.setAcctBal(custAumTransform(entity.getAcctBal()));
            vo.setTotNav(BigDecimal.valueOf(0));
            vos.add(vo);
        });

        workDkfinaExpireInfoEntities.forEach(entity->{
            SidebarProductExpireVO vo = new SidebarProductExpireVO();
            vo.setCustNo(entity.getCustNo());
            vo.setAvatar(radarContactService.getAvatarByCustNo(entity.getCustNo()));
            vo.setCustName(entity.getPecustName());
            vo.setMobile(entity.getMobileTel());
            vo.setCustMgrName(entity.getWarnPersonName());
            vo.setBelongOrgName(entity.getBelongOrg());
            vo.setWxExternalUserid(findWxExternalUseridByMobile(entity.getMobileTel(),mobileAndWxExternalUseridMapList));
            vo.setDataDate(DateUtil.parse(entity.getDataDt(), "yyyyMMdd").toDateStr());
            vo.setProductType("2");
            vo.setProductName(entity.getProductName());
            vo.setProductCode(entity.getProductCode());
            vo.setExpireDate(DateUtil.parse(entity.getDataDt(), "yyyyMMdd").toDateStr());
            vo.setAcctBal(custAumTransform(entity.getAcctBal()));
            vo.setTotNav(entity.getTotNav());
            vos.add(vo);
        });

        List<SidebarProductExpireVO> result = new ArrayList<>();
        if (!StrUtil.isBlank(queryParam)) {
            result = vos.stream()
                    .filter(vo -> vo.getCustName().contains(queryParam) || vo.getCustNo().equals(queryParam) || vo.getMobile().equals(queryParam))
                    .sorted(Comparator.comparing(SidebarProductExpireVO::getDataDate))
                    .collect(Collectors.toList());
        } else {
            result = vos.stream()
                    .sorted(Comparator.comparing(SidebarProductExpireVO::getDataDate))
                    .collect(Collectors.toList());
        }
        Page<SidebarProductExpireVO> resultPage = PageUtil.split(result, (int) page.getCurrent(), (int) page.getSize());
        //记录查看时间
        RemindContentViewTimeEntity viewTime = remindContentViewTimeService.getOne(new LambdaQueryWrapper<RemindContentViewTimeEntity>()
                .eq(RemindContentViewTimeEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(RemindContentViewTimeEntity::getWxUserId, wxUserId)
                .eq(RemindContentViewTimeEntity::getViewType, MarketingEventRemindTypeEnum.PRODUCT_EXPIRE.getCode()));
        RemindContentViewTimeEntity viewTimeEntity = new RemindContentViewTimeEntity();
        viewTimeEntity.setCorpId(CorpContextHolder.getCorpId());
        viewTimeEntity.setCurrentCount((int)resultPage.getTotal());
        viewTimeEntity.setWxUserId(wxUserId);
        viewTimeEntity.setViewTime(LocalDateTime.now());
        viewTimeEntity.setViewType(MarketingEventRemindTypeEnum.PRODUCT_EXPIRE.getCode());
        viewTimeEntity.setId(viewTime == null ? null : viewTime.getId());
        if (viewTime == null) {
            remindContentViewTimeService.save(viewTimeEntity);
        } else {
            remindContentViewTimeService.updateById(viewTimeEntity);
        }

        return resultPage;
    }

    @Override
    public IPage<SidebarBirthdayRemindVO> getBirthdayRemindPage(Page page, String wxUserId,String queryParam) {
        List<Map<String, String>> mobileAndWxExternalUseridMapList = contactService.getMobileAndWxExternalUseridByWxUserId(wxUserId);
        List<WorkImportantDaysInfoEntity> workImportantDaysInfoEntities = workImportantDaysInfoService.list(new LambdaQueryWrapper<WorkImportantDaysInfoEntity>()
                .eq(WorkImportantDaysInfoEntity::getWarnPerson, wxUserId));
        ArrayList<SidebarBirthdayRemindVO> vos = new ArrayList<>();
        workImportantDaysInfoEntities.forEach(entity->{
            SidebarBirthdayRemindVO vo = new SidebarBirthdayRemindVO();
            vo.setCustNo(entity.getCustNo());
            vo.setAvatar(radarContactService.getAvatarByCustNo(entity.getCustNo()));
            vo.setCustName(entity.getPecustName());
            vo.setMobile(entity.getMobile());
            vo.setBirthday(DateUtil.parse(entity.getImportantDt(), "yyyyMMdd").toDateStr());
            vo.setCustAum(custAumTransform(entity.getGnlAum()));
            vo.setCustMgrName(entity.getWarnPersonName());
            vo.setBelongOrgName(entity.getBelongOrg());
            vo.setWxExternalUserid(findWxExternalUseridByMobile(entity.getMobile(),mobileAndWxExternalUseridMapList));
            vo.setDataDate(DateUtil.parse(entity.getBusiDt(), "yyyyMMdd").toDateStr());
            vos.add(vo);
        });
        List<SidebarBirthdayRemindVO> result = new ArrayList<>();
        if (!StrUtil.isBlank(queryParam)) {
            result = vos.stream()
                    .filter(vo -> vo.getCustName().contains(queryParam) || vo.getCustNo().equals(queryParam) || vo.getMobile().equals(queryParam))
                    .sorted(Comparator.comparing(SidebarBirthdayRemindVO::getDataDate))
                    .collect(Collectors.toList());
        } else {
            result = vos.stream()
                    .sorted(Comparator.comparing(SidebarBirthdayRemindVO::getDataDate))
                    .collect(Collectors.toList());
        }
        Page<SidebarBirthdayRemindVO> resultPage = PageUtil.split(result, (int) page.getCurrent(), (int) page.getSize());

        //记录查看时间
        RemindContentViewTimeEntity viewTime = remindContentViewTimeService.getOne(new LambdaQueryWrapper<RemindContentViewTimeEntity>()
                .eq(RemindContentViewTimeEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(RemindContentViewTimeEntity::getWxUserId, wxUserId)
                .eq(RemindContentViewTimeEntity::getViewType, MarketingEventRemindTypeEnum.BIRTHDAY_REMIND.getCode()));
        RemindContentViewTimeEntity viewTimeEntity = new RemindContentViewTimeEntity();
        viewTimeEntity.setCorpId(CorpContextHolder.getCorpId());
        viewTimeEntity.setCurrentCount((int)resultPage.getTotal());
        viewTimeEntity.setWxUserId(wxUserId);
        viewTimeEntity.setViewTime(LocalDateTime.now());
        viewTimeEntity.setViewType(MarketingEventRemindTypeEnum.BIRTHDAY_REMIND.getCode());
        viewTimeEntity.setId(viewTime == null ? null : viewTime.getId());
        if (viewTime == null) {
            remindContentViewTimeService.save(viewTimeEntity);
        } else {
            remindContentViewTimeService.updateById(viewTimeEntity);
        }
        return resultPage;
    }

    @Override
    public IPage<SidebarCurrentBalanceVO> getCurrentBalancePage(Page page, String wxUserId, String custName, String custAum) {
        //CRM客户字典数据
        List<SysDictItem> crmDictList = remoteDictService.getCrmCustDict();

        List<Map<String, String>> mobileAndWxExternalUseridMapList = contactService.getMobileAndWxExternalUseridByWxUserId(wxUserId);
        List<WorkPreSavedeptInfoEntity> workPreSavedeptInfoEntities = workPreSavedeptInfoService.list(new LambdaQueryWrapper<WorkPreSavedeptInfoEntity>()
                .eq(WorkPreSavedeptInfoEntity::getWarnPerson, wxUserId));
        ArrayList<SidebarCurrentBalanceVO> vos = new ArrayList<>();
        workPreSavedeptInfoEntities.forEach(entity->{
            SidebarCurrentBalanceVO vo = new SidebarCurrentBalanceVO();
            vo.setCustNo(entity.getCustNo());
            vo.setAvatar(radarContactService.getAvatarByCustNo(entity.getCustNo()));
            vo.setCustName(entity.getPecustName());
            vo.setMobile(entity.getMobileTel());
            vo.setCustMgrName(entity.getWarnPersonName());
            vo.setBelongOrgName(entity.getBelongOrg());
            vo.setWxExternalUserid(findWxExternalUseridByMobile(entity.getMobileTel(),mobileAndWxExternalUseridMapList));
            vo.setDataDate(DateUtil.parse(entity.getDataDt(), "yyyyMMdd").toDateStr());
            vo.setAssetsLevel(valueToText(entity.getCustLevel(), CrmDictTypeConstants.TYPE_ASSETS_LEVEL,crmDictList));
            vo.setAvailableBal(custAumTransform(entity.getAvailableBal()));
            vos.add(vo);
        });
        List<SidebarCurrentBalanceVO> result = new ArrayList<>();
        if (!StrUtil.isBlank(custName) && StrUtil.isBlank(custAum)) {
            result = vos.stream()
                    .filter(vo -> vo.getCustName().contains(custName))
                    .sorted(Comparator.comparing(SidebarCurrentBalanceVO::getDataDate))
                    .collect(Collectors.toList());
        } else if (!StrUtil.isBlank(custAum) && StrUtil.isBlank(custName)) {
            Stream<SidebarCurrentBalanceVO> stream = vos.stream();
            switch (custAum) {
                case "1":
                    result = stream.filter(vo -> vo.getAvailableBal().equals("5万以下"))
                            .sorted(Comparator.comparing(SidebarCurrentBalanceVO::getDataDate))
                            .collect(Collectors.toList());
                    break;
                case "2":
                    result = stream.filter(vo -> vo.getAvailableBal().equals("5万-10万"))
                            .sorted(Comparator.comparing(SidebarCurrentBalanceVO::getDataDate))
                            .collect(Collectors.toList());
                    break;
                case "3":
                    result = stream.filter(vo -> vo.getAvailableBal().equals("10万-20万"))
                            .sorted(Comparator.comparing(SidebarCurrentBalanceVO::getDataDate))
                            .collect(Collectors.toList());
                    break;
                case "4":
                    result = stream.filter(vo -> vo.getAvailableBal().equals("20万以上"))
                            .sorted(Comparator.comparing(SidebarCurrentBalanceVO::getDataDate))
                            .collect(Collectors.toList());
                    break;
                default:
                    throw new IllegalArgumentException("参数custAum不合法");
            }
        } else if (!StrUtil.isBlank(custName) && !StrUtil.isBlank(custAum)) {
            Stream<SidebarCurrentBalanceVO> stream = vos.stream();
            switch (custAum) {
                case "1":
                    result = stream.filter(vo -> vo.getAvailableBal().equals("5万以下") && vo.getCustName().contains(custName))
                            .sorted(Comparator.comparing(SidebarCurrentBalanceVO::getDataDate))
                            .collect(Collectors.toList());
                    break;
                case "2":
                    result = stream.filter(vo -> vo.getAvailableBal().equals("5万-10万") && vo.getCustName().contains(custName))
                            .sorted(Comparator.comparing(SidebarCurrentBalanceVO::getDataDate))
                            .collect(Collectors.toList());
                    break;
                case "3":
                    result = stream.filter(vo -> vo.getAvailableBal().equals("10万-20万") && vo.getCustName().contains(custName))
                            .sorted(Comparator.comparing(SidebarCurrentBalanceVO::getDataDate))
                            .collect(Collectors.toList());
                    break;
                case "4":
                    result = stream.filter(vo -> vo.getAvailableBal().equals("20万以上") && vo.getCustName().contains(custName))
                            .sorted(Comparator.comparing(SidebarCurrentBalanceVO::getDataDate))
                            .collect(Collectors.toList());
                    break;
                default:
                    throw new IllegalArgumentException("参数custAum不合法");
            }
        } else {
            result = vos.stream()
                    .sorted(Comparator.comparing(SidebarCurrentBalanceVO::getDataDate))
                    .collect(Collectors.toList());
        }
        Page<SidebarCurrentBalanceVO> resultPage = PageUtil.split(result, (int) page.getCurrent(), (int) page.getSize());

        //记录查看时间
        RemindContentViewTimeEntity viewTime = remindContentViewTimeService.getOne(new LambdaQueryWrapper<RemindContentViewTimeEntity>()
                .eq(RemindContentViewTimeEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(RemindContentViewTimeEntity::getWxUserId, wxUserId)
                .eq(RemindContentViewTimeEntity::getViewType, MarketingEventRemindTypeEnum.CURRENT_BALANCE.getCode()));
        RemindContentViewTimeEntity viewTimeEntity = new RemindContentViewTimeEntity();
        viewTimeEntity.setCorpId(CorpContextHolder.getCorpId());
        viewTimeEntity.setCurrentCount((int)resultPage.getTotal());
        viewTimeEntity.setWxUserId(wxUserId);
        viewTimeEntity.setViewTime(LocalDateTime.now());
        viewTimeEntity.setViewType(MarketingEventRemindTypeEnum.CURRENT_BALANCE.getCode());
        viewTimeEntity.setId(viewTime == null ? null : viewTime.getId());
        if (viewTime == null) {
            remindContentViewTimeService.save(viewTimeEntity);
        } else {
            remindContentViewTimeService.updateById(viewTimeEntity);
        }
        return resultPage;
    }

    @Override
    public IPage<SidebarMarketingClueVO> getMarketingCluePage(Page page, String wxUserId) {
        List<SidebarMarketingClueVO> result = new ArrayList<>();
        ArrayList<SidebarMarketingClueVO> vos = new ArrayList<>();
        List<MaMarketingLeadEntity> marketingLeadEntities = marketingLeadService.list(new LambdaQueryWrapper<MaMarketingLeadEntity>()
                .eq(MaMarketingLeadEntity::getRecommendId, wxUserId)
                .eq(MaMarketingLeadEntity::getMaDate,DateUtil.format(DateUtil.yesterday(),"yyyy-MM-dd")));
        if (marketingLeadEntities.isEmpty()) {
            result = vos;
        } else {
            //distinctId去重
            List<String> distinctIds = marketingLeadEntities.stream()
                    .map(entity -> entity.getDistinctId())
                    .distinct()
                    .collect(Collectors.toList());
            //关联客户雷达列表
            Collection<RadarContactEntity> radarContactEntities = radarContactService.listByIds(distinctIds);
            distinctIds.forEach(distinctId->{
                SidebarMarketingClueVO vo = getSidebarMarketingClueVO(distinctId, marketingLeadEntities, radarContactEntities);
                vo.setDataDate(DateUtil.format(DateUtil.yesterday(),"yyyy-MM-dd"));
                vos.add(vo);
            });
            result = vos;
        }
        Page<SidebarMarketingClueVO> resultPage = PageUtil.split(result, (int) page.getCurrent(), (int) page.getSize());

        //记录查看时间
        RemindContentViewTimeEntity viewTime = remindContentViewTimeService.getOne(new LambdaQueryWrapper<RemindContentViewTimeEntity>()
                .eq(RemindContentViewTimeEntity::getCorpId, CorpContextHolder.getCorpId())
                .eq(RemindContentViewTimeEntity::getWxUserId, wxUserId)
                .eq(RemindContentViewTimeEntity::getViewType, MarketingEventRemindTypeEnum.MARKETING_CLUE.getCode()));
        RemindContentViewTimeEntity viewTimeEntity = new RemindContentViewTimeEntity();
        viewTimeEntity.setCorpId(CorpContextHolder.getCorpId());
        viewTimeEntity.setCurrentCount((int)resultPage.getTotal());
        viewTimeEntity.setWxUserId(wxUserId);
        viewTimeEntity.setViewTime(LocalDateTime.now());
        viewTimeEntity.setViewType(MarketingEventRemindTypeEnum.MARKETING_CLUE.getCode());
        viewTimeEntity.setId(viewTime == null ? null : viewTime.getId());
        if (viewTime == null) {
            remindContentViewTimeService.save(viewTimeEntity);
        } else {
            remindContentViewTimeService.updateById(viewTimeEntity);
        }
        return resultPage;
    }

    @Override
    public IPage<SidebarMarketingClueDetailsVO> getMarketingClueDetailsPage(Page page, String distinctId) {
        List<MaMarketingLeadDetailsEntity> marketingLeadDetailsEntities = marketingLeadDetailsService.list(new LambdaQueryWrapper<MaMarketingLeadDetailsEntity>()
                .eq(MaMarketingLeadDetailsEntity::getDistinctId, distinctId)
                .eq(MaMarketingLeadDetailsEntity::getMaDate,DateUtil.format(DateUtil.yesterday(),"yyyy-MM-dd")));

        ArrayList<SidebarMarketingClueDetailsVO> vos = new ArrayList<>();
        //总共浏览时长
        Integer totalDuration = 0;
        for (MaMarketingLeadDetailsEntity entity : marketingLeadDetailsEntities) {
            SidebarMarketingClueDetailsVO vo = new SidebarMarketingClueDetailsVO();
            vo.setBrowses(entity.getBrowses());
            //float类型取整
            vo.setDuration(Math.round(entity.getDuration()));
            vo.setProductName(entity.getLeadDesc());
            vo.setProductType(entity.getLeadName());
            vos.add(vo);
            totalDuration += Math.round(entity.getDuration());
        }
        Page<SidebarMarketingClueDetailsVO> resultPage = PageUtil.split(vos, (int) page.getCurrent(), (int) page.getSize());
        SubPage subPage = new SubPage();
        HashMap<String, Object> map = new HashMap<>();
        map.put("totalDuration",totalDuration);
        map.put("dataDate",DateUtil.format(DateUtil.yesterday(),"yyyy-MM-dd"));
        subPage.setExtraProps(map);
        subPage.setRecords(resultPage.getRecords());
        subPage.setCurrent(resultPage.getCurrent());
        subPage.setSize(resultPage.getSize());
        subPage.setTotal(resultPage.getTotal());
        return subPage;
    }

    private SidebarMarketingClueVO getSidebarMarketingClueVO(String distinctId, List<MaMarketingLeadEntity> marketingLeadEntities, Collection<RadarContactEntity> radarContactEntities) {
        SidebarMarketingClueVO vo = new SidebarMarketingClueVO();
        vo.setDistinctId(distinctId);
        List<String> leadNames = marketingLeadEntities.stream()
                .filter(entity -> entity.getDistinctId().equals(distinctId))
                .map(entity -> entity.getLeadName())
                .distinct()
                .collect(Collectors.toList());
        vo.setProductTypeList(leadNames);
        List<RadarContactEntity> radarContactEntitie = radarContactEntities.stream()
                .filter(entity -> entity.getOpenId().equals(distinctId))
                .collect(Collectors.toList());
        if (!radarContactEntitie.isEmpty()) {
            vo.setAvatar(radarContactEntitie.get(0).getHeadimgurl());
            vo.setCustNo(radarContactEntitie.get(0).getCustNo());
            vo.setNickName(radarContactEntitie.get(0).getNickname());
            vo.setWxExternalUserid(radarContactEntitie.get(0).getWxExternalUserid());
            vo.setType(radarContactEntitie.get(0).getType());
            vo.setMobile(radarContactEntitie.get(0).getMobileTel());
        }
        return vo;
    }

    private String findWxExternalUseridByMobile(String mobile, List<Map<String, String>> mobileAndWxExternalUseridMapList) {
        String wxExternalUserid = "";
        if (mobileAndWxExternalUseridMapList.isEmpty()) {
            return wxExternalUserid;
        }
        for (Map<String, String> map : mobileAndWxExternalUseridMapList) {
            if (map.get("mobile").equals(mobile)) {
                wxExternalUserid = map.get("wxExternalUserid");
                return wxExternalUserid;
            }
        }
        return wxExternalUserid;
    }


    public static String custAumTransform(BigDecimal num) {
        if (num.compareTo(BigDecimal.valueOf(50000)) == -1) {
            return "5万以下";
        } else if (num.compareTo(BigDecimal.valueOf(50000)) > -1 && num.compareTo(BigDecimal.valueOf(100000)) == -1) {
            return "5万-10万";
        } else if (num.compareTo(BigDecimal.valueOf(100000)) > -1 && num.compareTo(BigDecimal.valueOf(200000)) == -1) {
            return "10万-20万";
        } else if (num.compareTo(BigDecimal.valueOf(200000)) > -1) {
            return "20万以上";
        } else {
            throw new IllegalArgumentException("参数异常!");
        }

    }

    private String valueToText(String dictValue, String dictType, List<SysDictItem> crmDictList) {
        List<String> textList = crmDictList.stream()
                .filter(l -> l.getType().equals(dictType) && l.getValue().equals(dictValue))
                .map(l->l.getLabel())
                .collect(Collectors.toList());
        if (textList.isEmpty()) {
            return dictValue;
        } else {
            return textList.get(0);
        }
    }


    /**
     * 发送成员营销事件提醒消息
     * @param corpId
     * @param response
     * @throws Exception
     */
    @Override
    public void sendMarketingEventRemindMsg(Integer corpId, HttpServletResponse response) {
        //获取企业下成员列表
        List<WorkEmployeeEntity> employeeEntities = employeeService.list(new LambdaQueryWrapper<WorkEmployeeEntity>()
                .select(WorkEmployeeEntity::getWxUserId)
                .eq(WorkEmployeeEntity::getCorpId, corpId));
        employeeEntities.forEach(employee->{
            //获取发送应用id
            String wxCorpId = corpService.getById(corpId).getWxCorpId();
            Integer agentId = corpService.getWxSendMsgAgentIdByWxCorpId(wxCorpId);

            //数据组装
            Map data = baseBuildData(corpId,employee.getWxUserId());
            if (data.isEmpty()) {
                log.info("该成员没有新的营销事件提醒消息,wxUserId:{}",employee.getWxUserId());
                return;
            }
            BehaviorTrackTextMsg msg = new BehaviorTrackTextMsg(employee.getWxUserId(),agentId,"text",data);
            log.info("behaviorTrackTextMsg:{}",msg);
            //消息推送
            WxApiUtils.sendMsgToEmployee(msg, corpId);
            log.info("消息发送完毕>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        });
    }

    private Map baseBuildData(Integer corpId,String wxUserId) {
        String content = "【营销事件提醒】\n" + "您有\n";
        Integer finaExpireNewestCount = workFinaExpireInfoService.getNewestCount(wxUserId);
        Integer dkfinaExpireNewestCount = workDkfinaExpireInfoService.getNewestCount(wxUserId);
        Integer importantDaysNewestCount = workImportantDaysInfoService.getNewestCount(wxUserId);
        Integer noCommunicationContactCount = getNoCommunicationContactCountByWxUserId(corpId,wxUserId);
        Integer marketingLeadNewestCount = marketingLeadService.getNewestCount(wxUserId);
        if ((finaExpireNewestCount + dkfinaExpireNewestCount) > 0) {
            content += "产品到期"+(finaExpireNewestCount+dkfinaExpireNewestCount)+"条\n";
        }
        if (importantDaysNewestCount > 0) {
            content += "生日到期"+importantDaysNewestCount+"条\n";
        }
        if (noCommunicationContactCount > 0) {
            content += "未交流客户"+noCommunicationContactCount+"人\n";
        }
        if (marketingLeadNewestCount > 0) {
            content += "营销线索"+marketingLeadNewestCount+"条\n";
        }
        content += "待您处理，<a href='" + BehaviorTrackFormatConst.Manager_View_URL + "'>点击查看详情</a>";
        List<String> datas = new ArrayList<>();
        datas.add(wxUserId);
        content = String.format(content, datas.toArray(new String[datas.size()]));
        Map data = new HashMap();
        if ((finaExpireNewestCount + dkfinaExpireNewestCount) == 0 &&
                importantDaysNewestCount == 0 &&
                noCommunicationContactCount == 0 &&
                marketingLeadNewestCount == 0) {
            return data;
        }
        data.put("content",content);
        return data;
    }
}
